package registry

import (
	"log"
	"slices"
	"time"
	"xin-job/admin/dao"
	"xin-job/core/biz"
)

var instance = &RegistryHelper{}

func GetInstance() *RegistryHelper {
	return instance
}

type RegistryHelper struct {
	stopFlag chan struct{}
}

func (r *RegistryHelper) Start() {
	go func() {
		defer func() {
			if err := recover(); err != nil {
				log.Printf("registry helper err=%v\n", err)
			}
		}()

		for {
			select {
			case <-r.stopFlag:
				// TODO 优雅停机
			default:
				// 查询所有自动注册的执行器
				groups := dao.FindByAddressType(0)
				if len(groups) > 0 {
					// 查询过期的执行器
					ids := dao.FindDead(90, time.Now())
					if len(ids) > 0 {
						// 删除过期心跳
						dao.RemoveDead(ids)
					}

					// 查询未过期的执行器
					registryList := dao.FindAll(90, time.Now())
					appAddressMap := make(map[string][]string)

					if len(registryList) > 0 {
						for _, item := range registryList {
							if item.RegistryGroup == "EXECUTOR" { // 自动注册
								appName := item.RegistryKey

								registryList, ok := appAddressMap[appName]
								if !ok {
									registryList = make([]string, 0)
								}

								if !slices.Contains(registryList, item.RegistryValue) {
									registryList = append(registryList, item.RegistryValue)
								}

								appAddressMap[appName] = registryList
							}
						}
					}

					for _, item := range groups {
						registryList := appAddressMap[item.AppName]

						if len(registryList) > 0 {
							var addressListStr string
							for i, address := range registryList {
								addressListStr = addressListStr + address
								if i < len(registryList)-1 {
									addressListStr = addressListStr + ","
								}
							}

							item.AddressList = addressListStr
							item.UpdateTime = time.Now()

							dao.UpdateGroup(&item)
						}
					}
				}

				// 睡眠30s
				time.Sleep(30 * time.Second)
			}
		}
	}()
}

func (r *RegistryHelper) Stop() {
	r.stopFlag <- struct{}{}
}

func (r *RegistryHelper) Registry(registryParam *biz.RegistryParam) biz.Return[string] {
	if registryParam.RegistryGroup == "" || registryParam.RegistryKey == "" || registryParam.RegistryValue == "" {
		return biz.Return[string]{Code: 500, Msg: "Illegal Argument."}
	}

	go func() {
		ret := dao.RegistryUpdate(registryParam.RegistryGroup, registryParam.RegistryKey, registryParam.RegistryValue)
		if ret < 1 {
			// 新增
			dao.RegistrySave(registryParam.RegistryGroup, registryParam.RegistryKey, registryParam.RegistryValue)
		}
	}()

	return biz.Return[string]{Code: 200}
}

func (r *RegistryHelper) RegistryRemove(registryParam *biz.RegistryParam) biz.Return[string] {
	if registryParam.RegistryGroup == "" || registryParam.RegistryKey == "" || registryParam.RegistryValue == "" {
		return biz.Return[string]{Code: 500, Msg: "Illegal Argument."}
	}

	go func() {
		dao.RegistryDel(registryParam.RegistryGroup, registryParam.RegistryKey, registryParam.RegistryValue)
	}()
	return biz.Return[string]{Code: 200}
}
